The following Q&As have code you might find useful.
Q. I am having trouble using sizeof() with printf(). For example:
printf("char size is %d.", sizeof(char));
outputs "char size is 0." Why do I get the wrong result?
A. The output is wrong because the return value of the sizeof() function is a size_t (an unsigned long). Use an %ld rather than a %d as a format specifier. Thus, the correct syntax is
"printf("The size of a char is %ld.", sizeof(char));"
Q. How can I avoid problems deleting heap objects whose references are on the stack when using exception handling? The pointer (which is on the stack) to the object becomes invalid when the stack unwinds and only the destructors for automatic objects are guaranteed to be called when an exception is thrown.
A. To handle this, declare pointers as volatile. Last month we explained why you should use the volatile type. Below is a practical example. Use volatile file pointers so that stack unwinding does not reset the value of the pointer (prohibiting the file from being closed).
funClass * volatile funClassPtr; // Syntax for volatile declaration
funClassPtr = NULL; // Pointer to NULL guarantees delete as safe.
int myInt = 1; // Watch in debugger to see
// the stack unwind.
try_ {
funClassPtr = TCL_NEW(funClass, ());//macro for new operator
myInt = 2; //put new value on stack
Failure (2, 100); // Force exception
}
catch_all_() { //catch block
delete funClassPtr; //this calls destructor.
// myInt is reset to 1, delete removes the object from the heap
}
end_try_ //end of try block
Q. How can I use exception handling without using the Think Class Library?
A. To use exception handling without the Think Class Library, include BRLib and Exceptions.cp in your project. Also, compile with the directive #define NO_TCL
The four macros used to make exception handling work correctly are:
AUTO_DESTRUCT_OBJECT
TCL_NEW
TCL_END_CONSTRUCTOR
TCL_START_DESTRUCTOR
The macro AUTO_DESTRUCT_OBJECT will guarantee that the destructor is called for an automatic object on the stack. A destructor will only work on a completely constructed object. TCL_END_CONSTRUCTOR helps the compiler to determine the complete construction of an object.
Here’s an example that shows how the macros are used.
class funClass TCL_AUTO_DESTRUCT_OBJECT //macro in class header
{
public:
funClass() { // no arg constructor
cout<< "In constructor."<<endl;
char * myStr = new char[64]; // allocate memory
TCL_END_CONSTRUCTOR // End of the constructor
}
virtual ~funClass() { // virtual destructor
TCL_START_DESTRUCTOR // Beginning of the destructor
cout<< "In destructor."<<endl;
delete [] myStr; // deallocate memory
}
};
Q. I have a program that I’m converting from DOS and would like to be able to draw some simple graphics to the console window. How can I do that?
A. Don’t do it. If you draw to the console window, you will not receive update events. However, if you just can’t help yourself from going down this path, here is how to do it.
#include <iostream.h>
WindowPtr myWindow; // To be used for the console window.
void main (void) {
cout << " "; //A simple way to show the console.
myWindow = FrontWindow(); //Get a pointer to the console.